import { creepCount } from "../../config"
import { creepRoleEnum, creepRuleNameEnum, taskType } from "../../enum"
import { objIDToObj, roomNameToObj, roomOwner } from "../../tools/baseTools"
import memoryData, { updateConstructionSiteBuildAmount } from "../../tools/memoryData"
import structureTool from "../../tools/tools/structureTool"
import eventManager from "../event/eventManager"
import { eventMap } from "../event/eventMap"
import progressManager from "../progressManager"
import taskManager, { publishSpawnTask, pushBuildTask, pushRepaireTask } from "../task/taskManager"

function _mountRoom() {
    Object.assign(Room.prototype, extension)
}

const extension = {
    taskPool: [],                       // 可接受的任务类型
    needRepairStructureTypePool: [STRUCTURE_ROAD, STRUCTURE_EXTENSION, STRUCTURE_SPAWN, STRUCTURE_CONTAINER],    // 需要维修的建筑类型
    init: function (params = {}) {
        this.memory['info'] = {}
        this.memory['info']['state'] = {}
        this.memory['info']['state']['isRuning'] = false
        this.memory['info']['state']['needFreeman'] = { isNeed: false }
        this.memory['info']['state']['needBuilder'] = { isNeed: false }
        this.memory['info']['state']['needHarvester'] = { isNeed: false }
        this.memory['info']['state']['needWallRepairer'] = { isNeed: false }
        this.memory['info']['publishTask'] = []
    },
    /**自检并执行任务*/
    run: function (params = {}) {
        let { owner = roomOwner(this) } = params
        if (!this.memory['info']) {
            // 对于游戏进行中遇到新遇到的房间，执行的初始化
            let newRoomParams = {
                room: this,
                roomName: this.name,
                owner: owner          // 房间归属
            }
            memoryData.init(newRoomParams)
            progressManager.init(newRoomParams)            // 游戏进程管理器
            taskManager.init(newRoomParams)                // 任务管理器
            this.init()
        }
        let objMemory = this.memory['info']['state']
        switch (owner) {
            case 0: // 属于我的房间                
                if (!objMemory.isRuning) {
                    // console.log(`${this.name}房间开始自检，检查内容为：房间内freeman数量，builder数量，是否有需要维修的建筑`);
                    let isRuning = false
                    // 非运行中，可执行任务
                    this.updateSelfState()
                    // 未发布任务，则进入自检，根据自检结果，判断是否发布任务
                    if (objMemory['needFreeman'].isNeed) isRuning = roomPublishSpawnFreemanTask(this)
                    if (objMemory['needBuilder'].isNeed) isRuning = roomPublishChangeBuilerRuleTask(this)
                    if (objMemory['needHarvester'].isNeed) isRuning = roomPublishSpawnHarvesterTask(this)
                    // if (objMemory['needWallRepairer'].isNeed) isRuning = roomPublishWallRepairerTask(this)
                    roomPublishRepairTask(this)
                    if (!isRuning) {
                        // 无任务，则进入休眠状态，一段时间后自动唤醒
                        objMemory.isRuning = true
                        eventManager.add(`${this.name}进入休眠,等待唤醒`, 30, eventMap.objToSleep, { objID: this.name })
                        // console.log(`${this.name}房间自检完成,无需发布任务,进入休眠等待10s后唤醒`);
                    } else {
                        console.log(`${this.name}房间自检完成,已发布任务${this.memory.info.publishTask.join()}`);
                    }
                }
                break;

            default:
                if (!objMemory.isRuning) {
                    objMemory.isRuning = true
                    eventManager.add(`${this.name}房间不属于我，进入长时间休眠`, 60, eventMap.objToSleep, { objID: this.name })
                    console.log('该房间不属于我,长时间间隔才进行一次自检');
                }
                break;
        }
    },
    /**检查自身状态，避免出现异常数据 */
    checkSelf: function (params = {}) {
        let { owner = roomOwner(this) } = params
        // 不同归属状态的房间存在不同的数据
        switch (owner) {
            case 0:
                // TODO:自动建造模块
                taskManager.checkSelf(this.name)
                break;

            default:
                break;
        }
    },

    /**更新自身状态 */
    updateSelfState: function () {
        // console.log(`${this.name}开始自检，更新当前房间需要的基础creep数据`);
        // 先根据当前发布的任务决定isNeed的初始值
        this.memory['info']['state']['needFreeman'].isNeed = true
        this.memory['info']['state']['needBuilder'].isNeed = true
        this.memory['info']['state']['needHarvester'].isNeed = true
        this.memory['info']['state']['needWallRepairer'].isNeed = true
        this.memory['info']['publishTask'].map(taskID => {
            let taskDeta = taskManager.getTaskByID(taskID, null, this.name, false)
            switch (taskDeta.taskType) {
                // 建筑任务
                case taskType.build:
                    this.memory['info']['state']['needBuilder'].isNeed = false
                    break;
                // 生产任务
                case taskType.spawnCreep:
                    switch (taskDeta.taskParams.role) {
                        case creepRoleEnum.worker.freeman:
                            this.memory['info']['state']['needFreeman'].isNeed = false
                            break;
                        case creepRoleEnum.worker.harvester:
                            this.memory['info']['state']['needHarvester'].isNeed = false
                            break;
                        case creepRoleEnum.worker.wallRepairer:
                            this.memory['info']['state']['needWallRepairer'].isNeed = false
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }
        })
        // console.log(`${this.name}自检后,是否需要freeman：${this.memory['info']['state']['needFreeman'].isNeed},是否需要harvester：${this.memory['info']['state']['needHarvester'].isNeed}是否存在需要创建creep的任务：${this.memory['info']['publishTask'].join()}`);
        // freeman数量
        if (this.memory['info']['state']['needFreeman'].isNeed) {
            this.memory['info']['state']['needFreeman'] = structureTool.isNeedCreep(this, creepRoleEnum.worker.freeman, creepCount.freeman[this.controller.level])
            if (this.memory['info']['state']['needFreeman'].isNeed) console.log(this.name + '房间freeman自检结果：' + JSON.stringify(this.memory['info']['state']['needFreeman']));
        }
        //needHarvester数量
        if (this.memory['info']['state']['needHarvester'].isNeed) {
            let isNeed = false
            /**前置条件需满足
             * 1. 控制中心等级大于2
             * 2. 存在container，且已经建造完成
             */
            if (this.controller.level >= 2) {
                let isOk = false
                if (Object.keys(this.memory['structure']['container']).length > 0) isOk = true
                // 数量满足
                let countLimit = Object.keys(this.memory.structure.source).reduce((a, id) => {
                    return a + this.memory.structure.source[id].collectPoint.length
                }, 0)
                // console.log('当前房间下所有的采集点统计值' + countLimit);
                if (isOk && this.memory.creeps['worker']['harvester'].length < Object.keys(this.memory['structure']['container']).length && this.memory.creeps['worker']['harvester'].length < countLimit) {
                    Object.keys(this.memory['structure']['source']).map(id => {
                        if (isNeed) return
                        if (this.memory['structure']['source'][id].acceptCreep) {
                            isNeed = true
                            this.memory['info']['state']['needHarvester'].isNeed = true
                            this.memory['info']['state']['needHarvester'].targetID = id
                            this.memory['info']['state']['needHarvester'].targetPos = this.memory['structure']['source'][id].pos
                        } else {
                            this.memory['info']['state']['needHarvester'].isNeed = false
                            this.memory['info']['state']['needHarvester'].targetID = null
                        }
                    })
                } else this.memory['info']['state']['needHarvester'].isNeed = false
            } else this.memory['info']['state']['needHarvester'].isNeed = false
            if (this.memory['info']['state']['needHarvester'].isNeed) console.log('Harvester自检结果' + JSON.stringify(this.memory['info']['state']['needHarvester']));
        }

        //needWallRepairer数量
        if (this.memory['info']['state']['needWallRepairer'].isNeed) {
            // 当前房间内的修墙工少于1个，且存在墙
            if (this.memory['structure'][STRUCTURE_WALL] && Object.keys(this.memory['structure'][STRUCTURE_WALL]).length != 0 && this.memory['creeps']['worker']['wallRepairer'].length < 1) {
                this.memory['info']['state']['needWallRepairer'].isNeed = true
            } else this.memory['info']['state']['needWallRepairer'].isNeed = false
        }

        // autoBuild数量
        if (this.memory['info']['state']['needBuilder'].isNeed) {
            updateConstructionSiteBuildAmount(this.name)
            if (this.memory.autoBuild.buildAmount != 0) {
                let needBuilderCount = Math.floor(this.memory.autoBuild.buildAmount / 4000) + 1
                this.memory['info']['state']['needBuilder'] = structureTool.isNeedCreep(this, creepRoleEnum.worker.freeman, needBuilderCount, creepRuleNameEnum.ruleBuilder)
            } else {
                this.memory['info']['state']['needBuilder'].isNeed = false
            }
            // console.log('更新room状态后的房间内建筑任务' + this.memory.task.taskType[taskType.build].join());
        }
    },
    /**获取任务 */
    getTask: function () {

    },
    /**自检并推送任务 */
    pushTask: function (params = {}) {
        let { owner = roomOwner(this) } = params

    }
}

/**杂工 */
function roomPublishSpawnFreemanTask(room, params = {}) {
    let { taskID = null } = params
    room = roomNameToObj(room)
    let taskDeta = {
        taskID: taskID || `${Game.time}时刻在${room.name}需要Freeman`,
        taskType: taskType.spawnCreep,
        publisherID: null,
        roomName: room.name,
        taskParams: {
            roomName: room.name,
            tag: 'worker',
            role: creepRoleEnum.worker.freeman,
            rule: creepRuleNameEnum.ruleFreeman,
            targetID: [],
            targetPos: room.controller.pos,
            params: {}
        }
    }
    publishSpawnTask(taskDeta)
    return true
}
/**建筑任务 */
function roomPublishChangeBuilerRuleTask(room) {
    room = roomNameToObj(room)
    let roomNeedBuilerMemory = room.memory['info']['state']['needBuilder']
    // console.log(`${room.name}房间存在${room.memory.autoBuild.buildAmount}工程量，需要${room.memory.info.state.needBuilder.expectAmount}个builder进行建筑`);
    // console.log(`${room.name}房间内建筑任务详情${JSON.stringify(room.memory['info']['state']['needBuilder'])}`);
    let needBuilder = room.memory.creeps.worker.freeman.length
    for (let index = 0; index < roomNeedBuilerMemory.expectAmount; index++) {
        if (needBuilder < roomNeedBuilerMemory.expectAmount) {
            // console.log('推送一个生产建筑工任务');
            roomPublishSpawnFreemanTask(room, { taskID: `${Game.time}时刻在${room.name}第${index + 1}次需要Freeman` })
            needBuilder++
        }
        // console.log('推送一个建筑任务');
        let taskID = `${room.name}存在${room.memory.autoBuild.buildAmount}点工程量, 需要第${index + 1}个建筑工`
        pushBuildTask(room, room.memory.autoBuild.constructionSite, { taskID: taskID })
    }
    return true
}
/**维修任务 */
function roomPublishRepairTask(room) {
    let repaireList = []
    room.needRepairStructureTypePool.map(structureType => {
        if (!room.memory.structure[structureType]) room.memory.structure[structureType] = {}    // 又是初始化问题，好烦
        Object.keys(room.memory.structure[structureType]).map(targetID => {
            let targetObj = objIDToObj(targetID)
            if (!targetObj) {// 不存在或建筑则删除                    
                delete room.memory['structure'][structureType][targetID]
                return
            }
            if (!targetObj.hits) {//不存在hit属性跳过
                return
            }
            // console.log(targetID + '的任务挂载前内存情况' + JSON.stringify(room.memory['structure'][structureType][targetID].publishTask))
            let targetMemory = room.memory['structure'][structureType][targetID]
            if (targetMemory.publishTask.length != 0) return    // 存在任务则跳过,TODO:后续增加一个校验任务环节？}
            // console.log('需要维修建筑物内存情况'+JSON.stringify(targetMemory));
            repaireList.push(targetID)
            const ratio = targetObj.hits / targetObj.hitsMax
            switch (true) {
                case ratio < 0.3:
                    // console.log(`${targetObj.name ? targetObj.name : targetObj.id}发布紧急维修任务`);
                    pushRepaireTask(room, targetObj, { isUrgent: true })
                    break;
                case ratio < 0.9:
                    // console.log(`${targetObj.name ? targetObj.name : targetObj.id}发布普通维修任务`);
                    pushRepaireTask(room, targetObj)
                    break;
                default:
                    repaireList.pop()
                    break;
            }
            // console.log(targetID + '的任务挂载后内存情况' + JSON.stringify(room.memory['structure'][structureType][targetID].publishTask))
        })
    })
    if (repaireList.length != 0) {
        console.log(`${room.name}房间存在需要维修的建筑，分别为:${repaireList.join()}`);
    }
    return true
}
/**专职采集者 */
function roomPublishSpawnHarvesterTask(room, params = {}) {
    let { taskID = null } = params
    room = roomNameToObj(room)
    let taskDeta = {
        taskID: taskID || `${Game.time}时刻在${room.name}需要Harvester`,
        taskType: taskType.spawnCreep,
        publisherID: null,
        roomName: room.name,
        taskParams: {
            roomName: room.name,
            tag: 'worker',
            role: creepRoleEnum.worker.harvester,
            rule: creepRuleNameEnum.ruleHarvester,
            targetID: [room.memory['info']['state']['needHarvester'].targetID],
            targetPos: room.memory['info']['state']['needHarvester'].targetPos,
            params: {}
        }
    }
    publishSpawnTask(taskDeta)
    return true
}
/**修墙工 */
function roomPublishWallRepairerTask(room, params = {}) {
    let { taskID = null } = params
    room = roomNameToObj(room)
    let taskDeta = {
        taskID: taskID || `${Game.time}时刻在${room.name}需要专职修墙工`,
        taskType: taskType.spawnCreep,
        publisherID: null,
        roomName: room.name,
        taskParams: {
            roomName: room.name,
            tag: 'worker',
            role: creepRoleEnum.worker.wallRepairer,
            rule: creepRuleNameEnum.ruleWallRepairer,
            targetID: [],
            targetPos: room.controller.pos,
            params: {}
        }
    }
    publishSpawnTask(taskDeta)
    return true
}
export default _mountRoom